"use strict";
cc._RF.push(module, 'c64ce5TWABPRLlk1MMhNw/U', 'MeshSdk');
// meshTools/tools/MeshSdk.js

"use strict";

(function (root, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : window.global = window || self, factory(global.MeshSDK = {}));
})(void 0, function (exports) {
  'use strict';

  var Protocal = function () {
    function Protocal(methodName, id, params, onComplete, onReceive, timeout) {
      var _this2 = this;

      var _this = this;

      var key = methodName + "_" + id;
      this._receiveName = key + "_receive";
      this._completeName = key + "_complete";
      params = params || {};
      params['receive'] = this._receiveName;
      params['jsCallback'] = this._completeName;

      if (methodName !== 'sendGameAction' && params.type !== 5) {
        console.log('[MeshH5]', 'params', params);
      }

      window[this._receiveName] = function (result) {
        console.log('[MeshH5]', 'native:', "methodName " + key + " received");
        window[_this._receiveName] = null;

        _this.done();

        if (onReceive) {
          onReceive(null, result);
        }
      };

      var flag = false;

      window[this._completeName] = function (result) {
        console.log('[MeshH5]', 'native:', "methodName " + key + " completed", result);
        flag = true;

        _this.dispose();

        if (onComplete) {
          onComplete(null, result);
        }
      };

      if (Utils.isIframe()) {
        if (methodName == 'sendGameAction') {
          if (params.type == 1) {
            flag = true;

            _this.dispose();

            return;
          }
        }

        window.addEventListener('message', function (e) {
          if (e.data && window[_this2._completeName]) {
            var data = e.data;
            var jsMethods = data.jsMethods;
            if (!jsMethods) return;
            if (jsMethods !== _this2._completeName) return;
            var jsData = data.jsData;
            if (!jsData) return;
            var result = MeshSDK.prototype.parseResult(undefined, jsData);
            if (!result) return;
            console.log('[MeshH5]', 'iFrame:', "methodName " + jsMethods + " completed", result);
            flag = true;

            _this.dispose();

            if (onComplete) {
              onComplete(null, result);
            }
          }
        }, false);
      }

      if (timeout > 0) {
        this._completeTimeoutId = setTimeout(function () {
          clearTimeout(_this._completeTimeoutId);

          if (onComplete && !flag) {
            _this.dispose();

            onComplete("methodName " + key + " not responding", null);
          }
        }, timeout);
      }
    }

    Protocal.prototype.onDone = function (callback) {
      if (this._receiveName && this._completeName) this._onDone = callback;
    };

    Protocal.prototype.done = function () {
      if (this._onDone) {
        this._onDone();

        this._onDone = undefined;
      }
    };

    Protocal.prototype.dispose = function () {
      this.done();
      window[this._receiveName] = null;
      delete window[this._receiveName];
      this._receiveName = null;
      window[this._completeName] = null;
      delete window[this._completeName];
      this._completeName = null;
      clearTimeout(this._completeTimeoutId);
    };

    Protocal.TIME_OUT_IN_MS = 1500;
    return Protocal;
  }();

  var Native = function () {
    function Native() {}

    Native.invoke = function (methodName, protocal, params, onComplete, onReceive, timeout) {
      var _this = this;

      if (timeout === void 0) {
        timeout = 5000;
      }

      var proto = this.createProtocal(methodName, params, onComplete, onReceive, timeout);

      if (proto) {
        var isIframe = Utils.isIframe();

        if (Utils.isAndroid()) {
          if (isIframe) {
            console.log('android iframe'); //向iframe发送消息

            window.parent.postMessage(JSON.stringify(params), "*");
          } else {
            if (protocal) {
              if (Utils.isUnity()) {
                protocal.call(window.Unity, JSON.stringify(params));
              } else {
                protocal.call(window.NativeBridge, JSON.stringify(params));
              }
            }
          }
        } else if (Utils.isIOS()) {
          if (isIframe) {
            console.log('ios iframe'); //向iframe发送消息

            window.parent.postMessage(JSON.stringify(params), "*");
          } else {
            if (protocal) {
              protocal.postMessage(JSON.stringify(params));
            }
          }
        } else {
          if (isIframe) {
            console.log('pc iframe'); //向iframe发送消息

            window.parent.postMessage(JSON.stringify(params), "*");
          } else {
            console.error('[MeshH5]', 'native:', 'invalid Android&Ios');
          }
        }
      } else {
        console.error('[MeshH5]', 'native:', 'invalid protocal initliazation');
      }
    };

    Native.createProtocal = function (methodName, params, onComplete, onReceive, timeout) {
      var total = this.PROTOCAL_CACHE[methodName] || 0;
      total += 1;
      this.PROTOCAL_CACHE[methodName] = total;
      return new Protocal(methodName, total, params, onComplete, onReceive, timeout);
    };

    Native._allIFrames = [];
    Native._iframeId = -1;
    Native.PROTOCAL_CACHE = {};
    return Native;
  }();

  var isAndroid = function isAndroid() {
    var u = navigator.userAgent;
    return u.indexOf('Android') > -1 || u.indexOf('Adr') > -1;
  };

  var isIOS = function isIOS() {
    var u = navigator.userAgent;
    return !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
  };

  var isIframe = function isIframe() {
    return window.top !== window;
  };

  var isUnity = function isUnity() {
    return window['isUnity'];
  };

  var nativeCall = Native.invoke.bind(Native);
  var Utils = Object.freeze({
    nativeCall: nativeCall,
    isAndroid: isAndroid,
    isIOS: isIOS,
    isIframe: isIframe,
    isUnity: isUnity
  });

  var MeshSDK = function () {
    function MeshSDK() {
      /*注册H5接受消息*/
      this._wrappedConfigParams = {
        //用户token发生变化
        'serverCodeUpdate': function serverCodeUpdate(handler, result) {
          var cb = handler,
              data = result;

          if (cb) {
            cb(data);
          }
        },
        //用户货币发生变化
        'walletUpdate': function walletUpdate(handler, result) {
          var cb = handler,
              data = result;

          if (cb) {
            cb(data);
          }
        },

        /**
         * 游戏行为发生变化
         * 物理返回键:{
         *     type:1
         * }
         * 返回按钮显示状态:{
         *     type:2,
         *     showStatus:0 隐藏 1 显示
         * }
         * 观众人数变化:{
         *     type:3,
         *     audienceCount:1//最新观众人数
         * }
         * APP操作游戏座位
         *      1.收到sendGameAction 上/下游戏座位 type:15
         *      2.通过APP麦位上座游戏座位(按需调用)
         *      3.收到sendGameAction 同步座位信息 type:16 时，发现座位信息同麦位信息不一致时，
         *        以APP麦位信息为准，进而保证两者的一致性。(按需调用)
         * :{
         *      type:4,
         *      params:{
         *          optType:0,//0上座,1下座
         *          userId:xxxA,
         *          seat:0 // 座位位置
         *      }
         * }
         * 变更用户身份
         * {
         *     type:5,
         *     params:{
         *         role:0,//0.正常用户 1.游客  2.主持人(拥有开始游戏权限)
         *         userId:xxxA
         *     }
         * }
         * APP返回踢人操作结果
         * {
         *     type:6,
         *     params:{
         *         optResult:0,//0 踢人成功 1 踢人失败
         *         optUserId:0,//执行踢人操作用户id
         *         userId:xxxA,//被踢用户id
         *         reason:"success" //optResult 为1时，需要注明原因
         *     }
         * }
         * @param handler
         * @param result
         * 活动入口ICON状态 (psd):
         * {
         *     type:2001,
         *     showStatus:0 隐藏 1 显示
         *     activityIcon:'' 活动icon 外网访问地址 (120*120 px)
         * }
         *
         * 打开帮助
         * {
         *     type:2002
         * }
         *
         * 控制游戏背景音乐 0-1
         * {
         *     type:2003,
         *     bgVolume:0.5
         * }
         *
         * 控制游戏音效 0-1
         * {
         *     type:2004,
         *     soundVolume:0.5
         * }
         *
         * 麦位图标底部到屏幕顶部距离/屏幕高度
         * 数值范围 0-1
         * {
         *     type:2005,
         *     value:0.1
         * }
         *
         * 帮助按钮显示状态:{
         *     type:2006,
         *     showStatus:0 隐藏 1 显示
         * }
         *
         * musee 最小化按钮显示状态:{
         *     type:2007,
         *     showStatus:0 隐藏 1 显示
         * }
         * 客户端通知游戏最小化状态
         * {
         *     type:2008,
         *     minimizeStatus:0 取消最小化 1 启用最小化
         * }
         * tietie 控制游戏内的按钮点击逻辑
         * {
         *   type:2009,
         *   params:{
         *       "subAction":2009,
         *       "subMsg":{}
         *   }
         * }
         * 切换货币
         * {
         *     type:2010,
         *     params:{
         *          appId:xxx,
         *          coinType:1
         *      }
         * }
         * 隐藏设置按钮和商城按钮
         * {
         *     type:2011,
         *     params:{
         *         "settingButton": false,  //设置按钮是否隐藏（true显示，false隐藏，默认显示）
         *         "mallButton": false, //商城按钮是否隐藏（true显示，false隐藏，默认显示）
         *         "subMsg": {} //保留字段可不传
         *     }
         * }
         * 查询当前音乐和音效的状态
         * {
         *     type:2012,
         *     params:{}
         * }
         * 直接触发游戏内的事件（拉起商城、拉起规则页）
         * {
         *     type:2013,
         *     params:{
         *         //1001 拉起规则页面  //1002拉起商城页面 //1003设置音效和音乐相关的
         *         "subAction": 1001,
         *         "subMsg": {
         *                     //在subAction为 1003 的时候传bgmStatus、seStatus字段
         *                     "bgmStatus": 1, //背景音乐 bgmStatus 0 关闭 1 打开
         *                     "seStatus": 1 //音效 seStatus 0 关闭 1 打开
         *                   }
         *     }
         * }
         */
        'gameActionUpdate': function gameActionUpdate(handler, result) {
          var cb = handler,
              data = result;

          if (cb) {
            cb(data);
          }
        },

        /**
         * 声音发生变化
         * 背景音乐 bgmStatus 0 关闭 1 打开
         * 音效 seStatus 0 关闭 1 打开
         * {bgmStatus:1,seStatus:1}
         * @param handler
         * @param result
         */
        'soundUpdate': function soundUpdate(handler, result) {
          var cb = handler,
              data = result;

          if (cb) {
            cb(data);
          }
        },

        /**
         * musee 恢复游戏面板
         * 游戏 恢复音量
         */
        'openFoldGame': function openFoldGame(handler, result) {
          var cb = handler,
              data = result;

          if (cb) {
            cb(data);
          }
        }
      };
    }
    /**
     * 创建协议
     * @param fnName 方法名
     */


    MeshSDK.prototype.createProtocol = function (fnName) {
      var isIframe = Utils.isIframe();

      if (Utils.isAndroid()) {
        if (isIframe) {
          console.log('android iframe');
        } else if (Utils.isUnity()) {
          if (window.Unity && window.Unity['call']) {
            return window.Unity['call'];
          } else {
            return null;
          }
        } else {
          if (window.NativeBridge && window.NativeBridge[fnName]) {
            return window.NativeBridge[fnName];
          } else {
            return null;
          }
        }
      } else if (Utils.isIOS()) {
        if (isIframe) {
          console.log('ios iframe');
        } else if (Utils.isUnity()) {
          if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers['unityControl']) {
            return window.webkit.messageHandlers['unityControl'];
          } else {
            return null;
          }
        } else {
          if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers[fnName]) {
            return window.webkit.messageHandlers[fnName];
          } else {
            return null;
          }
        }
      } else {
        if (isIframe) {
          console.log('pc iframe');
        } else {
          console.error('[Mesh-H5-sdk]', "createProtocol 既不是Andoroid也不是Ios");
        }
      }
    };
    /**
     * 通用的处理结果的方法
     * @param err 错误信息
     * @param result 成功的结果，一般是字符串，需要JSON.parse处理
     * @returns {*}
     */


    MeshSDK.prototype.parseResult = function (err, result) {
      if (err) throw err;else if (result == undefined || result == null) throw 'empty result';else {
        var parsed = void 0;

        if (typeof result == 'string') {
          parsed = JSON.parse(result);
        } else if (typeof result == 'object') {
          parsed = result;
        }

        if (!parsed) throw 'failed to parse';
        return parsed;
      }
    };
    /**
     * 辅助方法，用来方便创建统一的协议回调处理逻辑
     * @param resolve 通过 promise 传入的 resolve 回调
     * @param reject 通过 promise 传入的 reject 回调
     */


    MeshSDK.prototype.usePromiseResult = function (resolve, reject) {
      var _this = this;

      return function (err, result) {
        try {
          var parsed = _this.parseResult(err, result);

          if (parsed) {
            resolve(parsed);
          }
        } catch (e) {
          reject(e);
        }
      };
    };
    /**
     * 发送协议的接口。
     * 一般情况下无需主动调用
     * @param params 构造出来的协议参数，包括协议名和参数等
     * @param onComplete 完成回调
     * @param onReceive 接收到回调
     */


    MeshSDK.prototype.send = function (params, onComplete, onReceive) {
      if (!params) return;
      Utils.nativeCall(params.methodName, params.protocol, params.params, onComplete, onReceive, params.timeout);
    };
    /**
     * 通用的请求协议的方法。可以参照协议文档进行调用。
     * @param methodName 方法函数名
     * @param params 协议参数，JSON Object
     * @param onComplete 协议完成回调方法
     * @param onReceived 协议收到回调方法（ACK）
     * @param timeout 超时，单位毫秒。默认 0 为不超时。超时设置的用处是清空回调等资源。
     */


    MeshSDK.prototype.request = function (methodName, params, onComplete, onReceived, timeout) {
      if (timeout === void 0) {
        timeout = 0;
      }

      this.send({
        methodName: methodName,
        protocol: this.createProtocol(methodName),
        params: params,
        timeout: timeout
      }, this.usePromiseResult(onComplete, function (reason) {
        return console.error('[Mesh-H5-sdk]', "methodName " + methodName + " error: " + reason);
      }), onReceived);
    };

    MeshSDK.prototype.regReceiveMessage = function (params) {
      var _this = this;

      var wrapped = {};

      for (var key in params) {
        if (!!_this._wrappedConfigParams[key]) {
          wrapped[key] = key;
        }
      }

      if (Utils.isIframe()) {
        window.addEventListener('message', function (e) {
          if (e.data) {
            var data = e.data;
            var jsMethods = data.jsMethods;
            if (!params[jsMethods]) return;
            var jsData = data.jsData;
            if (!jsData) return;
            var result = MeshSDK.prototype.parseResult(undefined, jsData);
            if (!result) return;

            if (typeof params[jsMethods] === 'function' || !!_this._wrappedConfigParams[jsMethods]) {
              _this._wrappedConfigParams[jsMethods](params[jsMethods], result);
            }
          }
        });
      } else {
        // 把包裹后的方法注册到 window 上
        Object.keys(wrapped).forEach(function (key) {
          var name = wrapped[key];

          if (name) {
            if (name == 'openFoldGame') {
              window[name] = function (str) {
                if (typeof params[key] === 'function' || !!_this._wrappedConfigParams[key]) {
                  _this._wrappedConfigParams[key](params[key], {});
                }
              };
            } else {
              window[name] = function (str) {
                var result = _this.parseResult(undefined, str);

                if (!result) return;
                if (!params[key]) return;

                if (typeof params[key] === 'function' || !!_this._wrappedConfigParams[key]) {
                  _this._wrappedConfigParams[key](params[key], result);
                }
              };
            }
          }
        });
      }

      return wrapped;
    };
    /**
     * 获取版本号(H5SDK 协议)
     * @returns {Promise<unknown>}
     */


    MeshSDK.prototype.getVersion = function () {
      return new Promise(function (resolve) {
        var data = "1.0.0";
        resolve(data);
      });
    };
    /**
     * 获取用户信息配置
     * @returns {Promise<unknown>}
     */


    MeshSDK.prototype.getConfig = function () {
      var _this = this;

      return new Promise(function (resolve, reject) {
        _this.request("getConfig", {}, function (data) {
          resolve(data);
        }, reject);
      });
    };
    /**
     * 销毁游戏
     * @returns {Promise<unknown>}
     */


    MeshSDK.prototype.destroy = function () {
      var _this = this;

      return new Promise(function (resolve, reject) {
        _this.request("destroy", {}, function (data) {
          resolve(data);
        }, reject);
      });
    };
    /**
     * 提示余额不足，拉起充值商城
     * type 0：余额不足 1：余额充足，主动调用
     * gameId：游戏Id
     * paymentType
     *   trovo: 1: mana; 2: game coin
     *   musee: 1:黄钻 2:蓝钻
     * inThisRound: 本轮是否参与 0:未参与  1:参与
     * @returns {Promise<unknown>}
     */


    MeshSDK.prototype.gameRecharge = function (params) {
      var _this = this;

      return new Promise(function (resolve, reject) {
        _this.request("gameRecharge", params ? params : {}, function (data) {
          resolve(data);
        }, reject);
      });
    };
    /**
     * 游戏加载完毕
     * @returns {Promise<unknown>}
     */


    MeshSDK.prototype.gameLoaded = function () {
      var _this = this;

      return new Promise(function (resolve, reject) {
        _this.request("gameLoaded", {}, function (data) {
          resolve(data);
        }, reject);
      });
    };
    /**
     * musee
     * 最小化按钮
     * 调用时游戏执行静音操作(不再执行，只是通知到最小化操作)
     * @returns {Promise<unknown>}
     */


    MeshSDK.prototype.foldGame = function () {
      var _this = this;

      return new Promise(function (resolve, reject) {
        _this.request("foldGame", {}, function (data) {
          resolve(data);
        }, reject);
      });
    };
    /**
     * 上报游戏行为
     * 游戏加载进度  type:1, params: {progress: 10}
     * 进入/打开游戏主页 type:2
     * 游戏房间号 type:3, params: {gameRoomId: 'xxxx'}
     * 网络延迟程度
     *   type:4,
     *   params:{
     *       status:1,延迟程度(1:良好 0~100ms,2:普通 100~200ms,3:较差 200~300ms,4:很差 300~600ms,5:极差 >600ms,6:断开网络 9999ms)
     *       latency:100,延迟时间，单位ms
     *   }
     * 帧率
     *   type:5,
     *   params:{
     *       status:1,帧率评级(1:超高 >60fps,2:高 50~60fps,3:中 30~50fps,4:较低 20~30fps,5:低 <20fps)
     *       fps:55,帧率值
     *   }
     * 拉起观众列表 type:6
     * 拉起玩家资料卡 type:7,params:{userId:xxx}
     * 获取用户是否已关注
     *    type:8,params:{userIds:[userId1xx,userId2xx]}
     *    返回数据：{
     *              userIds:{userId1xx:true,userId2xx:false}//true为已关注
     *            }
     * 关注用户
     *    type:9,params:{userId:xxx}
     *    返回数据：{
     *        status:0,//0 为关注成功,1 为关注失败
     *        userId:xxx,
     *    }
     * 拉起分享面板 type:10
     * 回到APP准备页(组队页) type:11
     * 点击右上角关闭按钮 type:12
     * 游戏开始 type:13
     * 游戏结束 type:14
     * 上/下游戏座位
     *    type:15
     *    params:{
     *        optType:0,//0上座,1下座
     *        userId:xxxA,
     *        seat:0 // 座位位置
     *    }
     * 同步座位信息
     *    type:16,
     *    params:{
     *      seats:[
     *          {
     *              userId:xxxA,
     *              seat:0, //座位位置
     *              prepareStatus:0 //0未准备,1已准备
     *          },
     *          {
     *              userId:xxxB,
     *              seat:1,
     *              prepareStatus:1,
     *          }
     *      ]
     *    }
     * 游戏发起踢人请求
     *    type:17,
     *    params:{
     *      userId:xxxA,
     *      seat:0 //座位位置
     *    }
     * 游戏上座失败
     *    type:18,
     *    params:{
     *        userId:xxxA,
     *    }
     * 是否可切换货币，游戏打开时状态为不可以切换
     *    type:19,
     *    params:{
     *        isCanChange: 0 不可切换 1 可切换
     *        currencyCoinType:1,//当前货币类型
     *    }
     * 语聊房游戏准备完成，通知 app 可以发起自动上座 type:20
     * 返回游戏内的音乐和音效状态（一般是收到gameActionUpdate中的 type ==2012 的时候发起回调）
     *    type: 21,
     *    params: {
     *         "bgmStatus": 1, //背景音乐 bgmStatus 0 关闭 1 打开
     *         "seStatus": 1   //音效 seStatus 0 关闭 1 打开
     *    }
     * 触发活动事件 psd专享()
     *    type:2001
     * 帮助页准备完毕
     *    type:2002
     *    params:{
     *        url:""
     *    }
     * 通知miya H5商城事件
     *  type:2003
     *  params:{
     *        env: 1 //1测试,2正式
     *        gameId:xxx
     *    }
     * 同步APP 麦克风和扬声器开关 游戏内通知 (比如拆弹猫、谁是卧底等）
     * {
     *     "type":3001,
     *     "params": {
     *         "users": [
     *                 {
     *                     "userId:": "xxxxx",   //用户 id
     *                     "microphone": false, //是否开启麦克风  false关闭  true开启
     *                     "useSpeaker": false //是否开启扬声器
     *                 },
     *                 {
     *                     "userId:": "xxxxx",
     *                     "microphone": true,
     *                     "useSpeaker": true
     *                 }
     *             ]
     *     }
     * }
     *
     * {
     *   "type": 3002,
     *   "params": {
     *     "state": 0 //0 代表点击的结算页面的关闭按钮   1 代表点击结算页面的再来一局按钮
     *   }
     * }
     * @returns {Promise<unknown>}
     */


    MeshSDK.prototype.sendGameAction = function (params) {
      var _this = this;

      return new Promise(function (resolve, reject) {
        _this.request("sendGameAction", params, function (data) {
          resolve(data);
        }, reject);
      });
    };
    /**
     * 是否支持isSupportRechargeV2
     * trovo 使用
     * @returns
     * isSupport boolean
     * true 去掉之前的Toast提示，调用gameRecharge paymentType =1
     * false 保留Toast
     */


    MeshSDK.prototype.isSupportRechargeV2 = function () {
      var _this = this;

      return new Promise(function (resolve) {
        var isSupport = false;

        if (Utils.isAndroid()) {
          if (window.NativeBridge['versionSupportApis']) {
            _this.request("versionSupportApis", {}, function (data) {
              if (data.apis && data.apis.includes('gameRechargeV2_trovo')) {
                isSupport = true;
              }

              resolve({
                'isSupport': isSupport
              });
            });
          } else {
            resolve({
              'isSupport': isSupport
            });
          }
        } else if (Utils.isIOS()) {
          if (window.webkit.messageHandlers['versionSupportApis']) {
            _this.request("versionSupportApis", {}, function (data) {
              if (data.apis && data.apis.includes('gameRechargeV2_trovo')) {
                isSupport = true;
              }

              resolve({
                'isSupport': isSupport
              });
            });
          } else {
            resolve({
              'isSupport': isSupport
            });
          }
        } else {
          isSupport = true;
          resolve({
            'isSupport': isSupport
          });
        }
      });
    };

    return MeshSDK;
  }();

  var meshSDK = new MeshSDK();
  exports.meshSDK = meshSDK;
  Object.defineProperty(exports, '__esModule', {
    value: true
  });
});

cc._RF.pop();